package com.studyyang.casedemo;

import com.rabbitmq.client.*;
import com.studyyang.utils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @Author yangjin
 * @Description
 * @Date 2021/10/27/23:47
 **/
public class ConsumerCase {

    public static void main(String[] args) throws IOException, TimeoutException {
        String QUEUE_NAME = "helloworld";
        //ConnectionFactory用于创建MQ的物理连接
        /*ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("81.70.239.179");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("admin");
        //创建TCP的物理连接
        Connection tcpConn = factory.newConnection();*/
        Connection tcpConn = RabbitmqUtils.getRabbitMqConn();
        //创建信道Channel，即为tcp连接当中的虚拟连接，信道之间互不干扰（若频繁创建TCP连接，耗费资源）
        Channel channel = tcpConn.createChannel();
        /**
         * queueDeclare:声明并创建队列（有则加载，无则创建）
         * 五个参数：
         * 1、队列名称
         * 2、是否持久化：true-是、false-否
         * 3、是否私有化：true-只有第一次拥有该队列的消费才可访问、false-所有消费者都可以访问该队列
         * 4、是否自动删除：true-连接断开之后自动删除该队列、false-反之不删除
         * 5、其它额外的参数：null
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        /**
         * 创建消费者
         * 1、队列名称
         * 2、是否自动确认消息：false-手动进行确认消息、true自动确认消息
         * 3、消费者实现类（DefaultConsumer的实现类）
         */
        channel.basicConsume(QUEUE_NAME, false, new Receiver(channel));
    }
}

class Receiver extends DefaultConsumer {

    public Channel channel;

    //重构构造函数，channel信道对象需要从外层传入，在消息处理handlerDelivery()要用到
    public Receiver(Channel channel) {
        super(channel);
        this.channel = channel;
    }

    @Override
    public void handleDelivery(String consumerTag, Envelope envelope,
                               AMQP.BasicProperties properties, byte[] body) throws IOException {
        /*super.handleDelivery(consumerTag, envelope, properties, body);*/
        //自定义消息签收
        String messageBody = new String(body);
        System.out.println("消费者接受到的消息："+ messageBody);
        /**
         * 手动确认签收消息：basicAck
         * 1、envelope.getDeliveryTag() 获取当前消息的TagId（角色id）
         * 2、是否消费所有消息：true-消费所有消息，false-消费当前接收到的消息
         */
        channel.basicAck(envelope.getDeliveryTag(),false);
    }
}
